package cn.wolfcode.luowowo.member.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.util.RedisKeysUtil;
import cn.wolfcode.luowowo.exception.LogicException;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.mapper.UserInfoMapper;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import cn.wolfcode.luowowo.util.AjaxResult;
import cn.wolfcode.luowowo.util.AssertUtil;
import cn.wolfcode.luowowo.util.Consts;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * @author win
 */
@Service
public class UserInfoServiceImpl implements IUserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private IUserInfoRedisService userInfoRedisService;


    @Override
    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public boolean checkPhone(String checkPhone) {
        AssertUtil.isPhoneNumber(checkPhone);
        // 如果已近发送验证码就 返回 true
        if (userInfoRedisService.verifyCodeVali(RedisKeysUtil.VERIFY_CODE_VALI.join(checkPhone))) {
            return true;
        }
        return !(userInfoMapper.selectCountByPhone(checkPhone) > 0);
    }

    @Override
    public void sendVerifyCode(String phone) throws LogicException {
        AssertUtil.isPhoneNumber(phone);
        if (userInfoRedisService.verifyCodeVali(RedisKeysUtil.VERIFY_CODE_VALI.join(phone))) {
            throw new LogicException("操作过于频繁!!!");
        }
        // 生成验证码
        String code = UUID.randomUUID().toString().substring(0, 6);
        // 将验证码存入 redis中
        System.out.println(code);
        userInfoRedisService.sendVerifyCode(RedisKeysUtil.VERIFY_CODE.join(phone), code, RedisKeysUtil.VERIFY_CODE.getTime());
        // 发送验证码
        System.out.println("您的验证码为:" + code + "请在" + Consts.VERIFY_CODE_VAI_TIME + "分钟内完成注册");

        //短信发送频率控制
        userInfoRedisService.sendVerifyCodeVali(RedisKeysUtil.VERIFY_CODE_VALI.join(phone), code, RedisKeysUtil.VERIFY_CODE_VALI.getTime());
    }

    @Override
    public void userRegist(String phone, String password, String rpassword, String nickname, String verifyCode) throws LogicException {
        AssertUtil.hasLength(phone, "手机号不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "验证密码不能为空");
        AssertUtil.hasLength(verifyCode, "验证码不能为空");
        // 验证是否是手机号
        AssertUtil.isPhoneNumber(phone);
        // 获取验证码
        String code = userInfoRedisService.getVerifyCode(RedisKeysUtil.VERIFY_CODE.join(phone));
        if (code == null) {
            throw new LogicException("验证码过期");
        }
        if (!code.equalsIgnoreCase(verifyCode)) {
            throw new LogicException("验证码错误");
        }
        if (!password.equals(rpassword)) {
            throw new LogicException("两次密码不匹配");
        }
        // 验证手机号是否存在
        if (!this.checkPhone(phone)) {
            throw new LogicException("该账户已经存在");
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(nickname);
        userInfo.setPhone(phone);
        userInfo.setPassword(password);
        userInfo.setState(UserInfo.STATE_NORMAL);
        userInfo.setHeadImgUrl("/images/default2.jpg");
        userInfo.setLevel(0);
        userInfoMapper.insert(userInfo);
    }

    @Override
    public String userLogin(String phone, String password) {
        // 验证手机号
        AssertUtil.isPhoneNumber(phone);
        // 密码验证
        AssertUtil.hasLength(password, "密码不能为空");
        // 验证用户信息是否正确
        UserInfo userInfo = userInfoMapper.selectUserByPhoneAndPassword(phone, password);
        if (userInfo == null) {
            throw new LogicException("用户名或密码错误");
        }
        // 生成 token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        // 将用户信息存入redis
        userInfoRedisService.addToken(RedisKeysUtil.USER_LOGIN_TOKEN.join(token), userInfo);
        // 返回token信息
        return token;
    }

    @Override
    public List<UserInfo> list() {
        return userInfoMapper.selectAll();
    }

    @Override
    public int getCountForAttention(Long id) {
        return userInfoMapper.getCountForAttention(id);
    }

    @Override
    public int getCountForFans(Long uid) {
        return userInfoMapper.getCountForFans(uid);
    }

    @Override
    public List<Long> getAttentionId(Long uid) {
        return userInfoMapper.getAttentionId(uid);
    }

    @Override
    public List<UserInfo> queryAttentionByIds(List<Long> attArray) {
        if (attArray == null || attArray.size() == 0){
            return Collections.emptyList();
        }
        return userInfoMapper.selectAttentionByIds(attArray);
    }

    @Override
    public Long saveOrUpdate(UserInfo userInfo) {
        if (userInfo.getId() != null) {
            userInfoMapper.updateByPrimaryKey(userInfo);
        } else {
            userInfoMapper.insert(userInfo);
        }
        return userInfo.getId();
    }

    @Override
    public void updateHeadImgUrl(String url, Long uid) {
        userInfoMapper.updateHeadImgUrl(url, uid);
    }

    @Override
    public void updateGoldMedal(int i, Long uid) {
        userInfoMapper.updateGoldMedal(i, uid);
    }

    @Override
    public void updatePhone(String phone, String newMobile) {
        List<String> allPhone = userInfoMapper.getAllPhone();
        if (allPhone.contains(newMobile)){
            throw new LogicException("该手机号已经被绑定");
        }
        userInfoMapper.updatePhone(phone,newMobile);
    }

    @Override
    public UserInfo selectJinPaiById(Long userId) {
        return userInfoMapper.selectJinPaiById(userId);
    }

    @Override
    public Boolean saveOrDelete(UserInfo userInfo, Long statusId, Long userId) {
        //userinfo.getid:当前登录用户
        //userId:提出问题的用户
        if (statusId == 0) {
            userInfoMapper.insertRelationship(userInfo.getId(), userId);
            return true;
        } else {
            userInfoMapper.deleteRelationship(userInfo.getId(), userId);
            return false;
        }
    }
}